package org.dicr.util.jds.report.gui;

import java.awt.*;
import java.util.*;
import java.util.List;

import javax.swing.*;
import javax.swing.event.*;

import org.dicr.event.*;
import org.dicr.gui.*;
import org.dicr.util.jds.report.*;

/***********************************************************************************************************************
 * @author Igor A Tarasov me@dicr.dn.ua
 * @version 030115
 **********************************************************************************************************************/
public class DataReportViewerPanel extends JPanel implements ChangeListener, ProgramEventGenerator, DicrDialogContent {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	protected ProgramEventMulticaster eventMulticaster = new ProgramEventMulticaster();

	protected JSplitPane split = new JSplitPane();

	protected JTabbedPane tabPane = new JTabbedPane();

	protected JScrollPane errorsScroll = new JScrollPane();

	protected MessagesPane errorsArea = new MessagesPane();

	protected DataReport report = null;

	public static final int EVENT_REPORT_CHANGED = 1;

	/*******************************************************************************************************************
	 * Конструктор
	 ******************************************************************************************************************/
	public DataReportViewerPanel() {
		try {
			jbInit();
		} catch (Exception ex) {
			DicrExceptionHandler.handleException(ex, this);
		}
	}

	/*******************************************************************************************************************
	 * Инициализация
	 ******************************************************************************************************************/
	private void jbInit() throws Exception {
		this.setLayout(new BorderLayout());
		this.add(this.split, BorderLayout.CENTER);
		this.split.setOrientation(JSplitPane.VERTICAL_SPLIT);
		this.split.setTopComponent(this.tabPane);
		this.split.setBottomComponent(this.errorsScroll);
		this.split.setResizeWeight(1);
		this.errorsScroll.setViewportView(this.errorsArea);
		Dimension scr = Toolkit.getDefaultToolkit().getScreenSize();
		this.setPreferredSize(new Dimension(scr.width * 4 / 5, scr.height * 4 / 5));
	}

	/*******************************************************************************************************************
	 * Определяет корректность обьекта отчета
	 ******************************************************************************************************************/
	protected boolean isValidReport() {
		return (this.report != null && this.report.getDocuments().size() > 0);
	}

	/*******************************************************************************************************************
	 * Обновляет окно просмотра при смене отчета
	 ******************************************************************************************************************/
	protected void reportChanged() {
		try {
			this.tabPane.removeAll();
			this.errorsScroll.setVisible(false);
			this.errorsArea.selectAll();
			this.errorsArea.cut();
			if (this.report != null) {
				Collection<DataReportDocument> docs = this.report.getDocuments();
				if (docs != null) {
					for (DataReportDocument doc : docs) {
						DocumentEditorPanel docEditor = new DocumentEditorPanel();
						docEditor.setContentType(doc.getContentType());
						docEditor.setDocument(doc.getDocument());
						this.tabPane.addTab(doc.getName(), docEditor);
					}
				}
				List<String> errors = this.report.getErrors();
				if (errors != null && errors.size() > 0) {
					this.errorsArea.addErrorMessages(errors);
					this.errorsScroll.setVisible(true);
				}
			}
		} finally {
			this.eventMulticaster.fireProgramEvent(new ProgramEvent(this, EVENT_REPORT_CHANGED, this.report));
		}
	}

	/*******************************************************************************************************************
	 * Установка отчета для просмотра
	 ******************************************************************************************************************/
	public void setReport(DataReport newReport) {
		if (newReport != this.report) {
			if (this.report != null) this.report.removeChangeListener(this);
			this.report = newReport;
			if (this.report != null) this.report.addChangeListener(this);
			reportChanged();
		}
	}

	/*******************************************************************************************************************
	 * Возвращает отчет
	 ******************************************************************************************************************/
	public DataReport getReport() {
		return this.report;
	}

	/*******************************************************************************************************************
	 * Добавляет слушателя
	 ******************************************************************************************************************/
	@Override
    public void addProgramListener(ProgramListener l) {
		this.eventMulticaster.addProgramListener(l);
	}

	/*******************************************************************************************************************
	 * Удаляет слушателя
	 ******************************************************************************************************************/
	@Override
    public void removeProgramListener(ProgramListener l) {
		this.eventMulticaster.removeProgramListener(l);
	}

	/*******************************************************************************************************************
	 * Обработка событий изменения отчета
	 ******************************************************************************************************************/
	@Override
    public void stateChanged(ChangeEvent e) {
		if (e.getSource() == this.report) {
			try {
				reportChanged();
			} catch (Exception ex) {
				DicrExceptionHandler.handleException(ex, this);
			}
		}
	}

	/*******************************************************************************************************************
	 * Добавляет слушателя
	 ******************************************************************************************************************/
	@Override
    public void addContentListener(ProgramListener l) {
	// NOP
	}

	/*******************************************************************************************************************
	 * Удаляет слушателя
	 ******************************************************************************************************************/
	@Override
    public void removeContentListener(ProgramListener l) {
	// NOP
	}

	/*******************************************************************************************************************
	 * Освобождает ресурсы
	 ******************************************************************************************************************/
	@Override
    public void shutdown() {
		this.setReport(null);
	}

	/*******************************************************************************************************************
	 * Создает диалог
	 ******************************************************************************************************************/
	public DicrDialog createDialog(Component parent, DataReport theReport) {
		String repName = "";
		if (theReport != null) {
			this.setReport(theReport);
			repName = theReport.getName();

		}
		return new DicrDialog(parent, "Отчет: " + repName, DicrDialog.DIALOG_SIMPLE, this);
	}

	/*******************************************************************************************************************
	 * Показывает диалоговое окно
	 ******************************************************************************************************************/
	public void showDialog(Component parent, DataReport theReport) {
		DicrDialog dialog = createDialog(parent, theReport);
		dialog.setVisible(true);
	}

	/*******************************************************************************************************************
	 * Показывает диалоговое окно
	 ******************************************************************************************************************/
	public void showDialog(Component parent) {
		showDialog(parent, null);
	}
}
